package org.anotes.springexample.aop.example1.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * User: gmc
 * Date: 13/04/12
 */
@Aspect
@Component("aspectExample1")
public class AspectExample {
    protected final Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("execution(* org.anotes.springexample.aop.example1.*.walk(..))")
    private void anyWalking() {
    }

    @Pointcut("execution(* org.anotes.springexample.aop.example1.*.walk(..)) and bean(painter)")
    private void painterWalking() {
    }

    @Pointcut("execution(* org.anotes.springexample.aop.example1.*.walk(..)) and bean(teacher)")
    private void teacherWalking() {
    }

    @Pointcut("execution(* org.anotes.springexample.aop.example1.*.*(..)) && bean(teacher)")
    private void teacherMethods() {
    }

    @Pointcut("within(org.anotes.springexample.aop.example1.*))")
    public void inPainterAndTeacherMethods() {
    }


    @Before("anyWalking()")
    public void logBeforeAnyWalking(JoinPoint joinPoint) {
        logger.info("Before walking:{}", joinPoint.getTarget());
    }

    @After("anyWalking()")
    public void logAfterAnyWalking() {
        logger.info("After walking");
    }

    @Before("teacherMethods() && args(param)")
    public void logPainterAndTeacherMethodWithStringArg(String param) {
        logger.info("Teacher Methods:Before methods with String parameter:{}", param);
    }

    @Around("inPainterAndTeacherMethods()")
    public void logAllMethodsPainterAndTeacher(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        logger.info("Around: Before executing:" + proceedingJoinPoint.getSignature());
        proceedingJoinPoint.proceed();
        logger.info("Around: After executing:" + proceedingJoinPoint.getSignature());
    }

}
